<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    // for这个词 强调过程 如何做 ，
    // forEach  map  some  every  reduce ：函数式编程思维   做什么？过程抽象

    //  1. forEach循环     for ： 强调过程 ，如何做 
    // 获取循环的键值   键名  及  原本数组

    // var arr = ['theshy', 'rookie', 'jackeylove']

    // 用法  
    // arr.forEach((item, ind, arr) => {
    //   console.log(item, ind, arr);
    // })

    // 1.1 实现的过程:
    // // 1.1.1  函数的定义
    // function myForEach (arr, fn) {
    //   for (var i = 0; i < arr.length; i++) {
    //     fn(arr[i], i, arr);
    //   }
    // }
    // // 1.1.2 函数的调用
    // myForEach(arr, function (item, key, arr) {
    //   console.log(item, key, arr);
    // })
    // 实现的效果和直接用arr.forEach 效果一样

    // 1.2 把方法挂载到Array的原型上
    // Array.prototype.myForEach = function (fn) {
    //   for (var i = 0; i < this.length; i++) {
    //     fn(this[i], i, this);
    //   }
    // }
    // arr.myForEach(function (item, key, arr) {
    //   console.log(item, key, arr);
    // })
    // 效果也是一样的

    // 2.map循环  映射 
    // var arr = ["张三", "李四", "王五"];
    // var res = arr.map(function (item, key, arr) {
    //     return item;
    // })
    // function mymap (arr, fn) {
    //   var result = [];
    //   for (var i = 0; i < arr.length; i++) {
    //     var res = fn(arr[i], i, arr);
    //     result.push(res);
    //   }
    //   return result;
    //   console.log(result);
    // }
    // mymap(arr)
    // var res = mymap(arr, function (item, key, arr) {
    //   console.log(item, key, arr);
    //   return item;
    // })
    // console.log(res);

    // forEach和map区别
    // map会返回一个新的数组，不会改变原来的数组  方便链式调用其他数组方法 如filter  reduce
    // forEach不会返回新数组，默认是undefined  允许对原数组进行修改。


    // 3. every和some
    // every &&  some  : ||
    // 每个结果都是true  every才是true  检测到一个false会停下      且
    // 有一个结果是true 那么就是true  遇到一个true  some循环会停止   或



    // 4. reduce  累加器
    // 4.1 数组累加
    // var arr = [1, 2, 3, 4];
    // var res = arr.reduce(function (pre, current) {
    //   pre.push(current + 10);
    //   return pre;
    // }, []);
    // console.log(res);

    // // 4.2 对象的累加
    // var arr = ['name', 'age', 3, 4];
    // var res = arr.reduce(function (pre, current) {
    //   pre[current] = 2;
    //   return pre;
    // }, {})
    // console.log(res);// {3: 2,4: 2,age: 2,name: 2}

    // 4.3 去重
    // reduce方法会遍历数组，并且为数组中的每个元素，执行定义的回调方法，并把结果汇总为单个值返回。


    // 1.通过reduce 给数组去重复 
    var arr = [5, 7, 5, 9, 5];
    // 2.var str = "abcabccaaa";  ----> {a:5,b:2,c:3}

    var str = "abcabccaaa";
    // console.log(str[1]) // 字符串也有索引 
    // var arr = [];
    // for (var i = 0; i < str.length; i++) {
    //   arr.push(str[i]);
    // }
    // console.log(arr);// 也可以遍历字符串

    var res = arr.reduce(function (pre, current) {
      // 核心： 判断 current ：a b c 存不存在？如果不存在 初始化一个 a:1 b:1 c:1
      // 存在 在以前的基础上 加一 a:1 ++ --->a:2
      typeof pre[current] === "undefined" ? pre[current] = 1 : pre[current]++;
      return pre;
    }, {});
    console.log(res); // 5:3    7:1    9:1




    // 最终版本 : reduce 去重
    // var arr = [1, 2, 2, 5];
    // var res = arr.reduce(function (pre, cur) {
    //   // 原理 reduce 会遍历四次数组
    //   // 第一次: 初始值是[] 赋值给pre cur是1  进入判断 去找索引 结果是-1  那么执行 pre.push(cur) 
    //   // 以此类推
    //   pre.indexOf(cur) === -1 ? pre.push(cur) : null;
    //   return pre;
    // }, []);
    // console.log(res);



  </script>
</body>

</html>